package org.example;

import org.example.data.PositionDataDetail;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.Socket;
import java.net.SocketException;
import java.text.DateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class AudioProcessor
{
    private String ip;
    private int port;

    private Socket socket;
    private Thread inStartThread;
    private Thread getStatusThread;
    InputStream inputStream;
    OutputStream outputStream;

    private int ATUO_START = 0;
    private static final Logger logger = LoggerFactory.getLogger(AudioProcessor.class);

//    构造方法
    public AudioProcessor(String ip, int port){
        this.ip = ip;
        this.port = port;

//        连接音频处理器
        try {
            socket = new Socket(ip,port);
            socket.setOOBInline(true);
            socket.setSoTimeout(7000);
            inputStream = socket.getInputStream();
            outputStream = socket.getOutputStream();
            processorStart();
        } catch (IOException e) {
            logger.error("音频处理器初始化异常");
            reconnect();
        }
    }

//    创建两个线程处理保持连接
    private void processorStart() {
        BufferedReader reader = new BufferedReader(new InputStreamReader(new BufferedInputStream(inputStream)));
//        尝试获取音频处理器状态
        getStatusThread = new Thread(new Runnable() {
            @Override
            public void run() {
                logger.info("运行了getStatusThread线程");

                while (!Thread.currentThread().isInterrupted()) {

                    try {
                        Thread.sleep(3000);

//                        socket.sendUrgentData("get  status \n".getBytes());
                        OutputStream outputStream1 = socket.getOutputStream();
                        outputStream1.write("get  status \n".getBytes());
                        outputStream1.flush();
                        logger.info("请求保持连接");
                    } catch (IOException e) {
                        logger.error("尝试保持连接失败，准备重新连接",e);
                        reconnect();
                        break;

                    } catch (InterruptedException e) {
                        logger.error("收到中断信号，准备退出",e);
                        Thread.currentThread().interrupt(); // 重新设置中断状态
                        if(reader != null){
                            try {
                                reader.close();
                            } catch (IOException ex) {
                                throw new RuntimeException(ex);
                            }
                        }
                        break;
                    }
                }
            }
        });
        getStatusThread.start();
//        接受状态线程
        inStartThread = new Thread(new Runnable() {
            @Override
            public void run() {
                logger.info("运行了inStartThread线程");
                while (!Thread.currentThread().isInterrupted()) {
                    try {
                        String line= null;
                        try {
                            line = reader.readLine();
                        } catch (IOException e) {
                            logger.error("读取超时,开始重新连接",e);
                            reconnect();
                            break;
                        }
                        String target = "cv \"status\" \"muted\" 1 1";
                        String target2 = "cv \"status\" \"unmuted\" 0 0";

                        if (target.equals(line) ) {
                            // 执行你的逻辑
                            ATUO_START = 1;
                            logger.info(line);
                        }
                        else if (target2.equals(line) ) {
                            ATUO_START = 0;
                            logger.info(line);

                        }
//                接受自动状态信息
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        // 收到中断信号，退出循环
                        logger.error("收到中断信号，准备退出",e);
                        Thread.currentThread().interrupt(); // 重新设置中断状态
                        break;
                    }
                }


            }
        });
        inStartThread.start();
    }
//    控制函数
    public void sendAudioData(String audioData){
        if (audioData == null || audioData.trim().isEmpty()) {
            logger.info("音频数据为空，跳过发送");
            return;
        }
        try {
            // 检查连接状态
            if (socket == null || !socket.isConnected() || socket.isClosed()) {
                logger.info("Socket未连接，尝试重新连接...");
                reconnect();
            }

            OutputStream outputStream = socket.getOutputStream();
            if(ATUO_START == 0)
            {
                outputStream.write(audioData.getBytes());
                logger.info("ATUO_START:"+ATUO_START+";"+audioData);

            }
//            outputStream.write("get  status \n".getBytes());

            outputStream.flush();

        } catch (IOException e) {
            reconnect();
        }
    }
//    资源释放
    public void close()
    {
        if(inputStream!=null){
            try {
                inputStream.close();
            } catch (IOException e) {
                logger.error("资源释放失败");
            }
        }
        if(outputStream!=null){
            try {
                outputStream.close();
            } catch (IOException e) {
                logger.error("资源释放失败");
            }
        }
        if (socket != null) {
            try {
                socket.close();
            } catch (IOException e) {
                logger.error("关闭旧连接时出错: ",e);
            }
        }
        if(inStartThread != null){
            inStartThread.interrupt();
        }
        if(getStatusThread != null) {
            getStatusThread.interrupt();
        }

    }

    /**
     * 重新连接方法
     */
    private synchronized void reconnect(){
//        1，释放资源
        close();
//        2，重新连接
        while(true)
        {
            try {
// 转换为可读格式


                logger.info("创建socket前"+new Date(System.currentTimeMillis()).toString());
                socket = new Socket(ip,port);
                logger.info("创建socket后"+new Date(System.currentTimeMillis()).toString());

                socket.setOOBInline(true);
                socket.setSoTimeout(7000);
                inputStream = socket.getInputStream();
                outputStream = socket.getOutputStream();
                logger.info("重新连接完成");

                break;
            } catch (IOException e) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e2) {
//                throw new RuntimeException(e);
                }
                logger.error("重新连接失败，尝试重新连接",e);
                close();
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
//                throw new RuntimeException(e);
            }
        }
//        3，启动线程
        processorStart();

    }


    //    音频处理器控制发送处理器
    public void autoSendProcessor(PositionDataDetail positionData){
        if(positionData.getDeviceName() != null)
        {
            String tagInfo = null;
//            在围栏外的标签
            if(positionData.getData().getFences() == null){
                tagInfo = positionData.getDeviceName();
                logger.info(tagInfo);

                // 正则表达式：匹配 T后面的数字，获取标签
                Pattern pattern = Pattern.compile("T(\\d+)");
                Matcher matcher = pattern.matcher(tagInfo);
                if (matcher.find()) {
                    String tNumber = matcher.group(1);  // 第一个捕获组：T后面的数字

                    // 如果需要整数类型
                    int tNum = Integer.parseInt(tNumber);
//                    System.out.println("csv mic" + tNum + "-0 1");
                    sendAudioData("csv mic" + tNum + "-0 1\n");
                } else {
                    logger.error("未获取到标签");
                }
                return;
            }

//            获取存在围栏的标签
            tagInfo = positionData.getDeviceName()+positionData.getData().getFences().get(0).getName();
            // 正则表达式：匹配 T后面的数字 和 Fence后面的数字
            Pattern pattern = Pattern.compile("T(\\d+)Fence-(\\d+)");
            Matcher matcher = pattern.matcher(tagInfo);
            if (matcher.find()) {
                String tNumber = matcher.group(1);  // 第一个捕获组：T后面的数字
                String fenceNumber = matcher.group(2); // 第二个捕获组：Fence后面的数字
                // 如果需要整数类型
                int tNum = Integer.parseInt(tNumber);
                int fenceNum = Integer.parseInt(fenceNumber);
                sendAudioData("csv mic" + tNum + "-" + fenceNum+" 1\n");

            } else {
                logger.error("未获取到标签");

            }


        }
    }


    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }


}
